-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enable react-hooks
lint rules
#11511
Conversation
🦋 Changeset detectedLatest commit: 9eaa883 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
size-limit report 📦
|
name = _callee.name; | ||
|
||
- if (name === 'useRef' && id.type === 'Identifier') { | ||
+ if ((name === 'useRef' || name === "useLazyRef") && id.type === 'Identifier') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot be configured, but we already have patch-package
in the repo, soooo.. 😏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, would we need this with the changes in #11403?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup - useLazyRef
is used in useFragment
.
src/react/hooks/useLazyQuery.ts
Outdated
const result: QueryResult<TData, TVariables> = Object.assign(useQueryResult, { | ||
called: !!execOptionsRef.current, | ||
}); | ||
useQueryResult.called = !!execOptionsRef.current; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was introducing a second variable, result
with a reference to useQueryResult
- so the code after this treated both these variables as different objects while in reality they were the same object.
I've eliminated result
here.
Alternatively, this might have been a mistake in the first place, and this should have been Object.assign({}, useQueryResult, { called })
, but I don't think so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's take the changes over in #11403 for anything useLazyQuery
. Feel free to add additional comments in that PR for any other changes you'd like to see from this PR.
That implementation now properly uses deps and tests for stale closures, so hopefully that hook is "fixed" in this regard in that PR.
src/react/hooks/useLazyQuery.ts
Outdated
@@ -112,8 +112,8 @@ export function useLazyQuery< | |||
|
|||
return promise; | |||
}, | |||
[] | |||
[eagerMethods, initialFetchPolicy, internalState] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eagerMethods
and internalState
are stable, but I believe initialFetchPolicy
could be modified at some point by updating the options of the underlying observableQuery
, which would not be picked up by execute
up until now.
watchQueryOptions, | ||
calledDuringRender, | ||
client, | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up until now, loadQuery
would not follow a new client
instance.
@jerelmiller this might be something we should still take into account for 3.9, or at least 3.9.1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call! I'm ok with doing a fast follow with 3.9.1 here if we want to keep with the code freeze. Thanks for finding!
src/react/hooks/useMutation.ts
Outdated
@@ -43,7 +43,7 @@ export function useMutation< | |||
client, | |||
}); | |||
|
|||
const ref = React.useRef({ | |||
const { current } = React.useRef({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lint rules had problems following deep access on ref.current.something
, and since current
is never reassigned I've destructured it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it even worth using a useRef
here anymore? Based on the number of changes I'm seeing here, it might be worth looking into more of a full refactor. Then again, I haven't run through these changes locally to best understand them, so perhaps this makes the most sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need something to hold a reference between renders. It could also be a useState
where we'd never call the setter.
@@ -251,8 +259,7 @@ class InternalState<TData, TVariables extends OperationVariables> { | |||
// effectively passing this dependency array to that useEffect buried | |||
// inside useSyncExternalStore, as desired. | |||
obsQuery, | |||
this.renderPromises, | |||
this.client.disableNetworkFetches, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.client.disableNetworkFetches
is never referenced within the callback, so the lint rules suggest to remove it. I assume that that's a good thing - ObservableQuery
doesn't have a concept of disableNetworkFetches
(it's a client
property) and unsubscribing/resubscribing will happen so fast that it doesn't trigger a new attempt to make a request anyways.
Am I missing anything here?
@@ -64,7 +64,7 @@ export function useReadQuery<TData>( | |||
forceUpdate(); | |||
}); | |||
}, | |||
[internalQueryRef] | |||
[internalQueryRef, queryRef] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If queryRef
changed, internalQueryRef
should have changed anyways, but it doesn't hurt to have it here to stick to the rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed
@@ -120,7 +120,7 @@ export function useSubscription< | |||
} | |||
|
|||
Object.assign(ref.current, { client, subscription, options }); | |||
}, [client, subscription, options, canResetObservableRef.current]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
canResetObservableRef
is a ref and it's current
value should not be used to trigger an effect, as changing it doesn't trigger a rerender and the resulting effect would be postponed to some random point in time in the future.
This might be a change in behaviour though - we need to be careful here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL we might have a tendency to overuse refs 😅
src/react/hooks/useSubscription.ts
Outdated
// This seems like a valid complaint and we should investigate that. | ||
// Generally: why is this a second `useEffect` and not part of the first one? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment 🙃
@@ -81,6 +81,8 @@ export const useSyncExternalStore: RealUseSESHookType = | |||
// Force a re-render. | |||
forceUpdate({ inst }); | |||
} | |||
// React Hook React.useLayoutEffect has a missing dependency: 'inst'. Either include it or remove the dependency array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tbh., I wouldn't touch our implementation of uSES
for now and remove it completely in 4.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. To be honest, I don't completely understand why we didn't just use the official polyfill to begin with, but it is what it is! Totally fine leaving this one as-is.
); | ||
|
||
const reset: ResetFunction = React.useCallback(() => { | ||
setQueryRef(null); | ||
}, [queryRef]); | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I wasn't careful enough in my own code review when we released this to catch this. Let's definitely get this change in a patch 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm generally in agreement with these changes. This is much needed!
For some of these, I think we'll just want to communicate some of the downstream effects in case we have users relying on the identity of some of these things that may now change more often (for good reasons). See this comment for an example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment on the wrong PR and I cannot delete this 🤦
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also in favor of these changes, thanks for putting this together Lenz!
✅ Deploy Preview for apollo-client-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for apollo-client-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Adding the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 will be nice to have this enabled
This PR adds the
react-hooks
linter rules and addresses some of the issues it raises - it's not meant for immediate merging, but mostly as a place where we can discuss the different issues. We will probably spin off a few individual PRs from this and then merge this in at the end when everything that needs addressing has been addressed.